package connect.impl

import connect.IBaseAction
import connect.IBaseUdpService
import java.net.DatagramPacket
import java.net.DatagramSocket
import java.net.InetAddress
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors

// 简单UDP服务
class UdpService private constructor() : IBaseUdpService {
    private var threadPoolExecutor: ExecutorService? = null
    private var resSocket: DatagramSocket? = null
    private var sendSocket: DatagramSocket? = null
    private val bufferSize = 8192
    var action: IBaseAction? = null

    // 单例模式
    companion object {
        fun getInstance(): UdpService {
            return UdpService()
        }
    }

    // 接收任务
    private val receiveStrTask = Runnable {
        while (true) {
            val byteArray = ByteArray(bufferSize)
            val packet = DatagramPacket(byteArray, byteArray.size)
            resSocket?.receive(packet)
            val msg = String(packet.data, 0, packet.length)
            action?.receiveMessage(msg, packet.address, packet.port)
        }
    }

    override fun init(port: Int) {
        threadPoolExecutor = Executors.newScheduledThreadPool(5)
        resSocket = DatagramSocket(port)
        sendSocket = DatagramSocket()
        if (threadPoolExecutor?.isShutdown == true) {
            return
        }
        threadPoolExecutor?.execute(receiveStrTask)
    }

    override fun isAlive(): Boolean {
        return threadPoolExecutor?.isShutdown == false
    }

    override fun dispose() {
        if (threadPoolExecutor?.isShutdown == false) {
            threadPoolExecutor?.shutdown()
        }
    }

    override fun sendUdpMessage(host: String, port: Int, msg: String) {
        val address = InetAddress.getByName(host)
        val msgByteArray = msg.toByteArray()
        if (msgByteArray.size >= bufferSize) {
            action?.onError("msg too length")
            return
        }
        val packet = DatagramPacket(msgByteArray, msgByteArray.size, address, port)
        sendSocket?.send(packet)
    }
}